﻿using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ViewMaker.Core.Utils;
using System.ComponentModel.Composition;
using ViewMaker.Core.ViewModels;
using ViewMaker.Core.Views;
using System.Windows.Markup;
using System.Diagnostics;

namespace ViewMaker.Core.Silverlight
{
    [Export(typeof(IViewContentGenerateService))]
    public class SlViewContentGenerateService : IViewContentGenerateService
    {

        public SlViewContentGenerateService()
        {
        }

        /// <summary>
        /// ViewModelのレイアウトを作成
        /// </summary>
        /// <param name="viewModel"></param>
        /// <param name="editable"></param>
        /// <returns></returns>
        public IViewContent BuildContent(object viewModel, ViewLayoutItem layout = null, bool editable = true)
        {
            layout = GenerateViewLayout(viewModel, layout);
            var content = new ContentControl();
            var target = BuildContent(content, viewModel, layout, editable);
            return new SlContentControlView(target, layout);
        }


        /// <summary>
        /// ViewModelのレイアウトを作成
        /// </summary>
        /// <param name="content"></param>
        /// <param name="viewModel"></param>
        /// <param name="editable"></param>
        /// <returns></returns>
        protected ContentControl BuildContent(ContentControl content, object viewModel, ViewLayoutItem layout, bool editable = true)
        {
            var xaml = ServiceLocator.GetService<IXamlGenerator>().Generate(layout);
            ContentControl target;

            try
            {
                target = (ContentControl)XamlReader.Load(xaml);
                target.DataContext = viewModel;
            }
            catch (XamlParseException ex)
            {
                Debug.WriteLine(ex.ToString());
                Debug.WriteLine(xaml);

                var line = ex.LineNumber > 0 ? xaml.Split('\n').Skip(ex.LineNumber - 1).First() : "";
                target = new ContentControl();
                target.Content = ex.Message + "\n" + line;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                Debug.WriteLine(xaml);
                target = new ContentControl();
                target.Content = ex.Message;
            }
            if (editable)
            {

                var vm = new ViewLayoutViewModel(layout, viewModel.GetType());
                new SlViewLayoutViewConnector(content, target, vm);
            }
            else
            {
                content.Content = target;
            }
            return target;
        }



        protected ViewLayoutItem GenerateViewLayout(object viewModel, ViewLayoutItem layout)
        {
            layout = layout ?? ServiceLocator.GetService<IViewLayoutGenerator>().Generate(viewModel);
            if (layout == null)
            {
                layout = layout ?? new ViewLayoutItem(null, "Empty", ViewControlType.StackPanel, null, false, "");
                layout.AddChild("Message", ViewControlType.Label).SetCaption("空");
            }
            return layout;
        }
    }
}
